package com.example.springboottest.example.gateway;

import reactor.core.publisher.Mono;
import reactor.util.function.Tuple3;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;

public class GatewayTest {
    public static void main(String[] args) {
        Mono<Entity1> entity1 = findEntity1("tom1", 25);
        Mono<Entity2> entity2 = findEntity2("tom2", 25);
        Mono<Entity3> entity3 = findEntity3("tom3", 25);


//        Mono<Void> combined = Mono.when(entity1, entity2, entity3);
        //这个是同步一个一个entity1、entity2和entity3的执行,如果是异步需要Mono.zip(monoAwithSubscribeOn, monoBwithSubscribeOn)
        Mono<Tuple3<Entity1, Entity2, Entity3>> combined = Mono.zip(entity1, entity2, entity3);

        Mono<String> entity = combined.map(tuple3 -> {
            System.out.println(tuple3.getT3().getName());
            System.out.println(tuple3.getT2().getName());
            System.out.println(tuple3.getT1().getName());
            return tuple3.getT3().getName() + "-" + tuple3.getT2().getName() + "-" + tuple3.getT1().getName();
        });

//        Mono.


        //通过阻塞方式获取值
//        System.out.println(entity.block());
        //通过非阻塞方式获取值
        entity.subscribe(System.out::println);
    }

    public static Mono<Entity1> findEntity1(String name, Integer age) {
        BiFunction<String, Integer, Entity1> fun1 = (n, a) -> {
            Entity1 entity1 = new Entity1();
            entity1.setName(n);
            entity1.setAge(a);
            return entity1;
        };
        try {
            System.out.println("enter findEntity1!");
            TimeUnit.SECONDS.sleep(1);
            System.out.println("findEntity1!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Mono.just(fun1.apply(name, age));
    }

    public static Mono<Entity2> findEntity2(String name, Integer age) {
        BiFunction<String, Integer, Entity2> fun1 = (n, a) -> {
            Entity2 entity1 = new Entity2();
            entity1.setName(n);
            entity1.setAge(a);
            return entity1;
        };
        try {
            System.out.println("enter findEntity2!");
            TimeUnit.SECONDS.sleep(2);
            System.out.println("findEntity2!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Mono.just(fun1.apply(name, age));
    }


    public static Mono<Entity3> findEntity3(String name, Integer age) {
        BiFunction<String, Integer, Entity3> fun1 = (n, a) -> {
            Entity3 entity1 = new Entity3();
            entity1.setName(n);
            entity1.setAge(a);
            return entity1;
        };
        try {
            System.out.println("enter findEntity3!");
            TimeUnit.SECONDS.sleep(3);
            System.out.println("findEntity3!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Mono.just(fun1.apply(name, age));
    }
}

class Entity1 {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

class Entity2 {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

class Entity3 {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
